/**
 * // Copyright (c) 2023 KylinOS. All rights reserved.
 * //
 * // This program is free software; you can redistribute it
 * // and/or modify it under the terms of the GNU General Public
 * // License (version 2) as published by the FSF - Free Software
 * // Foundation*
 */

/**
 * // Copyright (C) 2023 ben LG <guoliben@kylinos.cn>
 */

package docextractor

import (
	"bytes"
	"encoding/xml"
	"io"
	"os"
	"time"

	"gitee.com/guoliben/kydlp-doctotext/extractor_interface"
	"gitee.com/guoliben/kydlp-doctotext/utils/ctrlledprint"
)

type DocXml struct{}

func (extractor DocXml) GetTextFromFile(path string, size int64, filetype string, depth int) ([]byte, string) {
	ctrlledprint.Println("提取文本: 正在解析xml(file)文档...")

	return DocText{}.GetTextFromFile(path, size, filetype, depth)

	start := time.Now()

	file, err := os.Open(path)
	if err != nil {
		ctrlledprint.Println("Error opening xml file:", err)
		return nil, ""
	}
	defer file.Close()

	var text bytes.Buffer

	decoder := xml.NewDecoder(file)
	for {
		token, err := decoder.Token()
		if err != nil {
			if err == io.EOF {
				ctrlledprint.Println("End decoding xml file:", err)
			} else {
				ctrlledprint.Println("Error decoding xml file:", err)
			}
			break
		}

		switch token := token.(type) {
		case xml.CharData:
			// 如果是文本节点，将文本内容保存到变量中
			text.Write(token)
		}
	}

	elapsed := time.Since(start)

	return text.Bytes(), elapsed.String()
}

func (extractor DocXml) GetTextFromBuffer(path string, data []byte, size int64, filetype string, depth int) ([]byte, string) {
	ctrlledprint.Println("提取文本: 正在解析xml(buffer)文档...")

	return DocText{}.GetTextFromBuffer(path, data, size, filetype, depth)

	start := time.Now()

	var text bytes.Buffer

	// 创建 Decoder 对象
	decoder := xml.NewDecoder(bytes.NewReader(data))
	for {
		token, err := decoder.Token()
		if err != nil {
			if err == io.EOF {
				ctrlledprint.Println("End decoding xml file:", err)
			} else {
				ctrlledprint.Println("Error decoding xml file:", err)
			}
			break
		}

		switch token := token.(type) {
		case xml.CharData:
			// 如果是文本节点，将文本内容保存到变量中
			text.Write(token)
		}
	}

	elapsed := time.Since(start)

	return text.Bytes(), elapsed.String()
}

func (extractor DocXml) GetStringTextFromFile(path string, size int64, filetype string, depth int) (string, string) {
	ctrlledprint.Println("提取文本: 正在解析xml(file)文档...")

	return DocText{}.GetStringTextFromFile(path, size, filetype, depth)

	start := time.Now()

	file, err := os.Open(path)
	if err != nil {
		ctrlledprint.Println("Error opening xml file:", err)
		return "", ""
	}
	defer file.Close()

	var text bytes.Buffer

	decoder := xml.NewDecoder(file)
	for {
		token, err := decoder.Token()
		if err != nil {
			if err == io.EOF {
				ctrlledprint.Println("End decoding xml file:", err)
			} else {
				ctrlledprint.Println("Error decoding xml file:", err)
			}
			break
		}

		switch token := token.(type) {
		case xml.CharData:
			// 如果是文本节点，将文本内容保存到变量中
			text.Write(token)
		}
	}

	elapsed := time.Since(start)

	return text.String(), elapsed.String()
}

func (extractor DocXml) GetStringTextFromBuffer(path string, data []byte, size int64, filetype string, depth int) (string, string) {
	ctrlledprint.Println("提取文本: 正在解析xml(buffer)文档...")

	return DocText{}.GetStringTextFromBuffer(path, data, size, filetype, depth)

	start := time.Now()

	var text bytes.Buffer

	// 创建 Decoder 对象
	decoder := xml.NewDecoder(bytes.NewReader(data))
	for {
		token, err := decoder.Token()
		if err != nil {
			if err == io.EOF {
				ctrlledprint.Println("End decoding xml file:", err)
			} else {
				ctrlledprint.Println("Error decoding xml file:", err)
			}
			break
		}

		switch token := token.(type) {
		case xml.CharData:
			// 如果是文本节点，将文本内容保存到变量中
			text.Write(token)
		}
	}

	elapsed := time.Since(start)

	return text.String(), elapsed.String()
}

//func (extractor DocXml) GetTextFromFileWithCallback(path string, size int64, filetype string, depth int, callback extractor_interface.OnTextDetectHandler, context interface{}) (int, string, string) {
//	var retcode int
//
//	text, elapsed := extractor.GetTextFromFile(path, size, filetype, depth)
//
//	if callback != nil {
//		retcode, _ = callback(path, size, filetype, text, len(text), context)
//	}
//
//	return retcode, text, elapsed
//}
//
//func (extractor DocXml) GetTextFromBufferWithCallback(path string, data []byte, size int64, filetype string, depth int, callback extractor_interface.OnTextDetectHandler, context interface{}) (int, string, string) {
//	var retcode int
//
//	text, elapsed := extractor.GetTextFromBuffer(path, data, size, filetype, depth)
//
//	if callback != nil {
//		retcode, _ = callback(path, size, filetype, text, len(text), context)
//	}
//
//	return retcode, text, elapsed
//}

func (extractor DocXml) GetTextFromFileWithCallback(path string, size int64, filetype string, depth int, callback extractor_interface.OnTextDetectHandler, context interface{}) (int, []byte, string) {
	return DocText{}.GetTextFromFileWithCallback(path, size, filetype, depth, callback, context)
}

func (extractor DocXml) GetTextFromBufferWithCallback(path string, data []byte, size int64, filetype string, depth int, callback extractor_interface.OnTextDetectHandler, context interface{}) (int, []byte, string) {
	return DocText{}.GetTextFromBufferWithCallback(path, data, size, filetype, depth, callback, context)
}

func (extractor DocXml) GetStringTextFromFileWithCallback(path string, size int64, filetype string, depth int, callback extractor_interface.OnStringTextDetectHandler, context interface{}) (int, string, string) {
	return DocText{}.GetStringTextFromFileWithCallback(path, size, filetype, depth, callback, context)
}

func (extractor DocXml) GetStringTextFromBufferWithCallback(path string, data []byte, size int64, filetype string, depth int, callback extractor_interface.OnStringTextDetectHandler, context interface{}) (int, string, string) {
	return DocText{}.GetStringTextFromBufferWithCallback(path, data, size, filetype, depth, callback, context)
}
